package cn.roadtrip.mtravelbusinessmodule.bs.travelline;

import cn.roadtrip.mtravelbusinessmodule.dao.basic.vpo.SysCategoryItem;
import cn.roadtrip.mtravelbusinessmodule.dao.basic.vpo.SysTenantItem;
import cn.roadtrip.mtravelbusinessmodule.sql.couple.tables.SysCategory;
import cn.roadtrip.mtravelbusinessmodule.sql.couple.tables.SysTenant;
import cn.roadtrip.mtravelbusinessmodule.sql.couple.travelline.dto.BsScenicDTO;
import cn.roadtrip.mtravelbusinessmodule.sql.couple.travelline.tables.BsScenic;
import cn.roadtrip.mtravelbusinessmodule.sql.couple.travelline.tables.BsTravellinePretravellinescenicgroup;
import cn.roadtrip.mtravelbusinessmodule.sql.couple.travelline.tables.records.BsScenicRecord;
import cn.roadtrip.mtravelbusinessmodule.sql.couple.travelline.tables.records.BsTravellinePretravellinescenicgroupRecord;
import cn.roadtrip.mtravelbusinessmodule.sql.couple.travelline.vpo.VPO_ScenicGroupWithDetail;
import cn.roadtrip.utilmodule.util.DataBean;
import com.github.yitter.idgen.YitIdHelper;
import com.google.gson.Gson;
import lombok.*;
import lombok.extern.slf4j.Slf4j;
import org.jooq.DSLContext;
import org.jooq.impl.DSL;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.util.ArrayList;
import java.util.HashSet;
import java.util.stream.Collectors;

import static cn.roadtrip.mtravelbusinessmodule.bs.basic.BasicBusinessImpl.SYS_DICT_CITY_PRECODE;
import static cn.roadtrip.mtravelbusinessmodule.sql.couple.travelline.Tables.BS_SCENIC;
import static cn.roadtrip.mtravelbusinessmodule.sql.couple.travelline.Tables.BS_TRAVELLINE_PRETRAVELLINESCENICGROUP;

@Component
@Slf4j
public class ScenicImpl {
    @Autowired
    private DSLContext dslContext;


    /**
     * 查询出对应路线得分组旅游景点
     *
     * @param travelLineId
     * @return
     */
    public DataBean<java.util.Map<Integer, java.util.List<VPO_ScenicGroupWithDetail>>> _getScenicGroupByTravelLineId(String travelLineId) {
        try {
            java.util.Map<Integer, java.util.List<VPO_ScenicGroupWithDetail>> datas = dslContext.selectDistinct(
                            BS_TRAVELLINE_PRETRAVELLINESCENICGROUP.ID.as("gid"),
                            BS_TRAVELLINE_PRETRAVELLINESCENICGROUP.DEFAULTCHOICE,
                            BS_TRAVELLINE_PRETRAVELLINESCENICGROUP.DAYNUM,
                            BS_SCENIC.ID.as("scenicId"),

                            BS_SCENIC.TENANTID.as("tenantId"),
                            BS_SCENIC.TITLE.as("scenicTitle"),
                            BS_SCENIC.GIS.as("scenicGis"),
                            BS_SCENIC.ADDRESS.as("scenicAddress"),
                            BS_SCENIC.EXTINFOR.as("scenicExtInfor"),
                            BS_TRAVELLINE_PRETRAVELLINESCENICGROUP.SORTORDER.as("sortOrder")

                    ).from(
                            BS_TRAVELLINE_PRETRAVELLINESCENICGROUP,
                            BS_SCENIC
                    )
                    .where(
                            BS_TRAVELLINE_PRETRAVELLINESCENICGROUP.TRASH.eq(false)
                                    .and(BS_SCENIC.TRASH.eq(false))
                                    .and(BS_SCENIC.ID.eq(BS_TRAVELLINE_PRETRAVELLINESCENICGROUP.SCENICID))
                                    .and(BS_TRAVELLINE_PRETRAVELLINESCENICGROUP.TRAVELLINEID.eq(travelLineId))
                    )
                    .orderBy(DSL.field("sortOrder").asc())
                    .fetch()
                    .into(VPO_ScenicGroupWithDetail.class)
                    .stream()
                    .collect(Collectors.groupingBy(VPO_ScenicGroupWithDetail::getDayNum));
            if (datas == null || datas.isEmpty())
                return DataBean.suc(new java.util.HashMap<Integer, java.util.List<VPO_ScenicGroupWithDetail>>(), 0, "no-data", "没有数据");
            return DataBean.suc(datas, datas.size(), "suc", "操作成功");
        } catch (Exception e) {
            e.printStackTrace();
            return DataBean.err("err", e.getMessage());
        }
    }

    @Data
    @Builder
    @AllArgsConstructor
    @NoArgsConstructor
    @EqualsAndHashCode
    public static class Model_setScenicGroup {
        private String travelLineId;
        private String scenicId;
        private Boolean defualtChoice;
        private Integer dayNum;
        private Integer sortOrder;//排序
    }

    /**
     * 设置景区在路线中得组别
     *
     * @param models
     * @return
     */
    public DataBean setScenicGroup(java.util.List<Model_setScenicGroup> models) {
        java.util.Map<Integer, java.util.List<Model_setScenicGroup>> datas = models.stream().collect(Collectors.groupingBy(Model_setScenicGroup::getDayNum));//按日期分组
        //验证分组是否有效
        try {
            datas.forEach((k, v) -> {
                java.util.Set<String> ids = new HashSet<>();
                for (Model_setScenicGroup g : v) {
                    ids.add(g.getScenicId());
                }
                if (ids.size() != v.size()) {
//                    log.info("ids.size->{}  , v.size()->{} ", ids.size(), v.size());
                    throw new RuntimeException("同组别存在相同景点");
                }
                ids.clear();
            });
        } catch (Exception e) {
            e.printStackTrace();
            return DataBean.err("group-same-senic", e.getMessage());
        }

        try {
            return dslContext.transactionResult(ctx -> {
                //删除以前分组
                dslContext.update(BsTravellinePretravellinescenicgroup.BS_TRAVELLINE_PRETRAVELLINESCENICGROUP)
                        .set(BsTravellinePretravellinescenicgroup.BS_TRAVELLINE_PRETRAVELLINESCENICGROUP.TRASH, true)
                        .where(
                                BsTravellinePretravellinescenicgroup.BS_TRAVELLINE_PRETRAVELLINESCENICGROUP.TRASH.eq(false)
                                        .and(BsTravellinePretravellinescenicgroup.BS_TRAVELLINE_PRETRAVELLINESCENICGROUP.TRAVELLINEID.eq(models.get(0).getTravelLineId()))
                        ).execute();
                //开始分组
                java.util.List<BsTravellinePretravellinescenicgroupRecord> records = new ArrayList<>();
                for (Model_setScenicGroup g : models) {
                    records.add(new BsTravellinePretravellinescenicgroupRecord(
                            "" + YitIdHelper.nextId(),
                            false,
                            g.getTravelLineId(),
                            g.getScenicId(),
                            g.getDefualtChoice(),
                            g.getDayNum(),
                            g.getSortOrder()
                    ));
                }
                dslContext.batchInsert(
                        records
                ).execute();
                dslContext.commit();
                return DataBean.suc(true, 1, "suc", "操作成功");
            });
        } catch (Exception e) {
            e.printStackTrace();
            return DataBean.err("trans-err", e.getMessage());
        }


    }


    @Data
    @Builder
    @AllArgsConstructor
    @NoArgsConstructor
    @EqualsAndHashCode
    public static class Model_trashScenic {
        private String scenicId;
    }

    /**
     * 删除景区
     *
     * @param model
     * @return
     */
    public DataBean trashScenic(Model_trashScenic model) {
        try {
            return dslContext.transactionResult(ctx -> {
                dslContext.update(BsScenic.BS_SCENIC).set(BsScenic.BS_SCENIC.TRASH, true).where(BsScenic.BS_SCENIC.ID.eq(model.getScenicId())).execute();
                dslContext.commit();
                return DataBean.suc(true, 1, "suc", "操作成功");
            });
        } catch (Exception e) {
            e.printStackTrace();
            return DataBean.err("trans-err", e.getMessage());
        }
    }

    @Data
    @Builder
    @AllArgsConstructor
    @NoArgsConstructor
    @EqualsAndHashCode
    public static class Model_getScenicListByCity {
        private String cityName;
    }

    /**
     * 查询城市景区
     *
     * @param model
     * @return
     */
    public DataBean getScenicListByCity(Model_getScenicListByCity model) {

        //从字典查询出城市列表
        java.util.List<SysCategoryItem> cityList = dslContext.select(
                SysCategory.SYS_CATEGORY.ID,
                SysCategory.SYS_CATEGORY.NAME,
                SysCategory.SYS_CATEGORY.CODE
        ).from(
                SysCategory.SYS_CATEGORY
        ).where(
                SysCategory.SYS_CATEGORY.CODE.like(SYS_DICT_CITY_PRECODE + "%")
        ).fetch().into(SysCategoryItem.class);
        if (cityList.isEmpty()) {
            return DataBean.err("cityList-is-null", "没有找到当前城市");
        }

        SysCategoryItem currentCity = null;
        for (SysCategoryItem city : cityList) {
            if (city.getName().startsWith(model.getCityName())) {
                currentCity = city;
                break;
            }
        }
        if (currentCity == null) {
            return DataBean.err("city-null", "没有找到当前城市");
        }

        //从字典查询出租户列表
        java.util.List<SysTenantItem> tenantItemList = dslContext.select(
                        SysTenant.SYS_TENANT.ID,
                        SysTenant.SYS_TENANT.NAME,
                        SysTenant.SYS_TENANT.CITY_IDS
                ).from(SysTenant.SYS_TENANT)
                .where(SysTenant.SYS_TENANT.STATUS.eq(1))
                .fetch().into(SysTenantItem.class);

        //	3）从租户列表匹配出所在城市对应得租户
        Long tenantId = null;
        for (SysTenantItem tenantItem : tenantItemList) {
            String[] tids = tenantItem.getCityIds().split(",");
            for (String id : tids) {
                if (id.equals(currentCity.getId() + "")) {
                    tenantId = tenantItem.getId();
                    break;
                }
            }
            if (tenantId != null)
                break;
        }
        if (tenantId == null) {
            return DataBean.err("tenant-null", "当前城市没有对应的租户");
        }

        return getScenicListByTenant(new Model_getScenicListByTenant(tenantId + ""));
    }

    @Data
    @Builder
    @AllArgsConstructor
    @NoArgsConstructor
    @EqualsAndHashCode
    public static class Model_getScenicListByTenant {
        private String tenantId;
    }

    /**
     * 查询租户景区列表
     *
     * @param mode
     * @return
     */
    public DataBean getScenicListByTenant(
            Model_getScenicListByTenant mode
    ) {
        java.util.List<BsScenicDTO> list = new ArrayList<>();
        try {
            list = dslContext.selectFrom(BsScenic.BS_SCENIC)
                    .where(
                            BsScenic.BS_SCENIC.TRASH.eq(false)
                                    .and(BsScenic.BS_SCENIC.TENANTID.eq(mode.getTenantId()))
                    ).orderBy(BsScenic.BS_SCENIC.ID.desc(), BsScenic.BS_SCENIC.TITLE.asc())
                    .fetch().into(BsScenicDTO.class);
            return DataBean.suc(list, list.size(), "suc", "操作成功");
        } catch (Exception e) {
            e.printStackTrace();
            return DataBean.errEmpty();
        }
    }


    @Data
    @Builder
    @AllArgsConstructor
    @NoArgsConstructor
    @EqualsAndHashCode
    public static class Model_createScenic {
        private String tanentId;
        private String title;
        private String gis;
        private String cityId;
        private String address;
        private String ownCityName;
        private java.util.Map<String, Object> extInfor;
    }

    /**
     * 创建景区
     *
     * @param model
     * @return
     */
    public DataBean createScenic(Model_createScenic model) {
        try {
            model.setTitle(model.getTitle().trim());
            return dslContext.transactionResult(ctx -> {
                //查询是否有重名
                {
                    BsScenicRecord r = dslContext.selectFrom(BsScenic.BS_SCENIC)
                            .where(
                                    BsScenic.BS_SCENIC.TRASH.eq(false)
                                            .and(BsScenic.BS_SCENIC.TENANTID.eq(model.getTanentId()))
                                            .and(BsScenic.BS_SCENIC.TITLE.eq(model.getTitle()))
                            ).fetchOne();
                    if (r != null) {
                        return DataBean.err("scenic-repeat", "该景区已存在");
                    }
                }
                Gson gson = new Gson();
                BsScenicRecord record = dslContext.newRecord(BsScenic.BS_SCENIC);
                int count = dslContext.insertInto(BsScenic.BS_SCENIC).set(new BsScenicRecord(

                        YitIdHelper.nextId() + "",
                        false,
                        model.getTanentId(),
                        model.getOwnCityName(),
                        model.getCityId(),
                        model.getTitle(),
                        model.getGis(),
                        model.getAddress(),
                        model.getExtInfor() == null ? "{}" : gson.toJson(model.getExtInfor())
                )).execute();
                dslContext.commit();
                if (count > 0)
                    return DataBean.suc(true, 1, "suc", "操作成功");
                else throw new RuntimeException("插入失败");
            });
        } catch (Exception e) {
            e.printStackTrace();
            return DataBean.err("trans-err", e.getMessage());
        }
    }


    @Data
    @Builder
    @AllArgsConstructor
    @NoArgsConstructor
    @EqualsAndHashCode
    public static class Model_getScenicDetail {
        private String scenicId;
    }

    /**
     * 获取景点详情
     *
     * @param model
     * @return
     */
    public DataBean getScenicDetail(
            Model_getScenicDetail model
    ) {
        try {
            return dslContext.transactionResult(ctx -> {
                BsScenicDTO dto = dslContext.selectFrom(
                                BS_SCENIC
                        ).where(
                                BS_SCENIC.ID.eq(model.getScenicId())
                        ).limit(1)
                        .fetchOneInto(
                                BsScenicDTO.class
                        );
                if (dto == null) {
                    return DataBean.err("scenic-not-exist", "景点不存在");
                }
                dslContext.commit();
                return DataBean.suc(dto, 1, "suc", "操作成功");
            });
        } catch (Exception e) {
            e.printStackTrace();
            return DataBean.err("trans-err", e.getMessage());
        }
    }
}
